/* 
 * Data.java 12.05.2011
 *  
 *  
 * Candidate: Alessandra Otterbach
 * Prometric ID: Algisina1
 * Username: Algisina
 *  
 * Sun Certified Developer for Java 2 Platform, Standard Edition Programming 
 * Assignment (CX-310-252A)
 *  
 * This class is part of the Programming Assignment of the Sun Certified 
 * Developer for Java 2 Platform, Standard Edition certification program, must 
 * not be used out of this context and must be used exclusively by Sun 
 * Microsystems, Inc. 
 */
package suncertify.db;

import java.io.IOException;

/**
 * Implementation of the DB interface. Seperates the logic between DataManger and LockManager.
 * 
 * @author Alessandra Otterbach
 * 
 */
public class Data implements DB {

    /** Manages all the data action */
    private static DataManager dataManager = null;

    /** Manages all the locking action */
    private static LockManager lockManager = new LockManager();

    private static Data instance = new Data();

    /**
     * Private constructor, Singleton pattern, only one instance of this class
     * is allowed.
     */
    private Data() {

    }

    /**
     * Constructor with path as parameter. Pattern is a Singleton.
     * 
     * @param path
     * @return instance of data
     * @throws RecordNotFoundException
     * @throws IOException
     */
    public static Data getInstance(String path) throws IOException {
	dataManager = new DataManager(path);
	return instance;
    }

    @Override
    public String[] read(int recNo) throws RecordNotFoundException {
	return dataManager.read(recNo);
    }

    @Override
    public void update(int recNo, String[] data, long lockCookie)
	    throws RecordNotFoundException, SecurityException {
	// If the record to be updated doesn't exist, a RecordNotFoundException
	// is thrown
	if (!dataManager.checkRecordExists(recNo)) {
	    throw new RecordNotFoundException();
	}
	// Check if record is locked at all and with given lockCookie
	if (!lockManager.checkLocked(recNo, lockCookie)) {
	    throw new SecurityException();
	}
	dataManager.update(recNo, data);
    }

    @Override
    public void delete(int recNo, long lockCookie)
	    throws RecordNotFoundException, SecurityException {
	// If the record to be deleted doesn't exist, a RecordNotFoundException
	// is thrown
	if (!dataManager.checkRecordExists(recNo)) {
	    throw new RecordNotFoundException();
	}

	// Check if record is locked at all and with given lockCookie
	if (!lockManager.checkLocked(recNo, lockCookie)) {
	    throw new SecurityException();
	}

	dataManager.delete(recNo, lockCookie);
    }

    @Override
    public int[] find(String[] criteria) {
	return dataManager.find(criteria);
    }

    @Override
    public int create(String[] data) throws DuplicateKeyException {
	return dataManager.create(data);
    }

    @Override
    public long lock(int recNo) throws RecordNotFoundException {
	// If the record to be locked doesn't exist, a RecordNotFoundException
	// is thrown
	if (!dataManager.checkRecordExists(recNo)) {
	    throw new RecordNotFoundException();
	}
	return lockManager.lock(recNo);
    }

    @Override
    public void unlock(int recNo, long cookie) throws RecordNotFoundException,
	    SecurityException {
	// If the record to be unlocked doesn't exist, a RecordNotFoundException
	// is thrown
	if (!dataManager.checkRecordExists(recNo)) {
	    throw new RecordNotFoundException();
	}
	lockManager.unlock(recNo, cookie);
    }

    /**
     * Closes the database
     */
    public void setDatabaseLocked(boolean locked) {
	if (dataManager instanceof DataManager) {
	    ((DataManager) dataManager).cleanShutdown();
	}
    }
}
